﻿#region Includes
using System;
using System.IO;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Collections.Generic;

using OpenTK;
using OpenTK.Graphics.OpenGL;

using GingerGL.Graphics.Models.MD3;
#endregion

namespace GingerGL.Graphics.Models
{
    //------------------------------------------------------------//
    /// <summary>
    /// Internal Animation Tracking
    /// </summary>
    internal class QuakeAnimationTracker
    {
        //--------------------------------------------------------//
        #region Delegates & Events
        public delegate void SequenceEvent(QuakeAnimationTracker sender, string name);
        public event SequenceEvent AnimationLooped;
        public event SequenceEvent AnimationEnded;
        public event SequenceEvent FrameChanged;
        #endregion
        //--------------------------------------------------------//
        #region Variables
        private AnimationSequence sequence;
        private double lastTime = -1;
        private Stopwatch timer;
        #endregion
        //--------------------------------------------------------//
        #region Properties
        /// <summary>
        /// Gets this frame :)
        /// </summary>
        public int ThisFrame { get; private set; }
        #endregion
        //--------------------------------------------------------//
        #region Constructors
        /// <summary>
        /// Initializes a new instance of object
        /// </summary>
        /// <param name="seq">Sequence</param>
        public QuakeAnimationTracker(AnimationSequence seq)
        {
            sequence = seq;
            timer = new Stopwatch();
            timer.Start();
            ThisFrame = seq.StartFrame;
        }
        #endregion
        //--------------------------------------------------------//
        #region Methods
        /// <summary>
        /// Update the Animation Tracker
        /// </summary>
        public void Update()
        {
            double now = timer.ElapsedMilliseconds / 1000.0;

            if (ThisFrame < sequence.StartFrame || ThisFrame > sequence.EndFrame || lastTime < 0) // starting over
            {
                ThisFrame = sequence.StartFrame;
                lastTime = now;
            }
            else
            {
                float fps = sequence.FPS * QuakeModel.FPSScale;

                if (now > lastTime + (1.0 / fps))
                {
                    ThisFrame++;
                    if (ThisFrame > sequence.EndFrame)
                    {
                        ThisFrame = sequence.LoopPoint;
                        if (sequence.LoopPoint == sequence.EndFrame)
                            if (AnimationEnded != null) AnimationEnded(this, sequence.Name);
                            else
                                if (AnimationLooped != null) AnimationLooped(this, sequence.Name);
                    }
                    lastTime = now;
                    if (FrameChanged != null) FrameChanged(this, sequence.Name);
                }
            }
        }
        #endregion
        //--------------------------------------------------------//
    }
    //------------------------------------------------------------//
}
